/**
 * @file lv_nv3007.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "lv_nv3007.h"

#if LV_USE_NV3007

/*********************
 *      DEFINES
 *********************/

#define NV3007_SLPIN 0x10
#define NV3007_SLPOUT 0x11

#define NV3007_INVOFF 0x20
#define NV3007_INVON 0x21
#define NV3007_DISPOFF 0x28
#define NV3007_DISPON 0x29

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/

/**********************
 *  STATIC CONSTANTS
 **********************/

/* init commands based on ArduinoGFX NV3007 driver */
static const uint8_t init_cmd_list[] = {
    0x9a, 1, 0x08,
    0x9b, 1, 0x08,
    0x9c, 1, 0xb0,
    0x9d, 1, 0x16,
    0x9e, 1, 0xc4,
    0x8f, 2, 0x55, 0x04,
    0x84, 1, 0x90,
    0x83, 1, 0x7b,
    0x85, 1, 0x33,
    0x60, 1, 0x00,
    0x70, 1, 0x00,
    0x61, 1, 0x02,
    0x71, 1, 0x02,
    0x62, 1, 0x04,
    0x72, 1, 0x04,
    0x6c, 1, 0x29,
    0x7c, 1, 0x29,
    0x6d, 1, 0x31,
    0x7d, 1, 0x31,
    0x6e, 1, 0x0f,
    0x7e, 1, 0x0f,
    0x66, 1, 0x21,
    0x76, 1, 0x21,
    0x68, 1, 0x3A,
    0x78, 1, 0x3A,
    0x63, 1, 0x07,
    0x73, 1, 0x07,
    0x64, 1, 0x05,
    0x74, 1, 0x05,
    0x65, 1, 0x02,
    0x75, 1, 0x02,
    0x67, 1, 0x23,
    0x77, 1, 0x23,
    0x69, 1, 0x08,
    0x79, 1, 0x08,
    0x6a, 1, 0x13,
    0x7a, 1, 0x13,
    0x6b, 1, 0x13,
    0x7b, 1, 0x13,
    0x6f, 1, 0x00,
    0x7f, 1, 0x00,
    0x50, 1, 0x00,
    0x52, 1, 0xd6,
    0x53, 1, 0x08,
    0x54, 1, 0x08,
    0x55, 1, 0x1e,
    0x56, 1, 0x1c,

    0xa0, 3, 0x2b, 0x24, 0x00,

    0xa1, 1, 0x87,
    0xa2, 1, 0x86,
    0xa5, 1, 0x00,
    0xa6, 1, 0x00,
    0xa7, 1, 0x00,
    0xa8, 1, 0x36,
    0xa9, 1, 0x7e,
    0xaa, 1, 0x7e,
    0xB9, 1, 0x85,
    0xBA, 1, 0x84,
    0xBB, 1, 0x83,
    0xBC, 1, 0x82,
    0xBD, 1, 0x81,
    0xBE, 1, 0x80,
    0xBF, 1, 0x01,
    0xC0, 1, 0x02,
    0xc1, 1, 0x00,
    0xc2, 1, 0x00,
    0xc3, 1, 0x00,
    0xc4, 1, 0x33,
    0xc5, 1, 0x7e,
    0xc6, 1, 0x7e,
    0xC8, 2, 0x33, 0x33,
    0xC9, 1, 0x68,
    0xCA, 1, 0x69,
    0xCB, 1, 0x6a,
    0xCC, 1, 0x6b,
    0xCD, 2, 0x33, 0x33,
    0xCE, 1, 0x6c,
    0xCF, 1, 0x6d,
    0xD0, 1, 0x6e,
    0xD1, 1, 0x6f,
    0xAB, 2, 0x03, 0x67,
    0xAC, 2, 0x03, 0x6b,
    0xAD, 2, 0x03, 0x68,
    0xAE, 2, 0x03, 0x6c,
    0xb3, 1, 0x00,
    0xb4, 1, 0x00,
    0xb5, 1, 0x00,
    0xB6, 1, 0x32,
    0xB7, 1, 0x7e,
    0xB8, 1, 0x7e,
    0xe0, 1, 0x00,
    0xe1, 2, 0x03, 0x0f,
    0xe2, 1, 0x04,
    0xe3, 1, 0x01,
    0xe4, 1, 0x0e,
    0xe5, 1, 0x01,
    0xe6, 1, 0x19,
    0xe7, 1, 0x10,
    0xe8, 1, 0x10,
    0xea, 1, 0x12,
    0xeb, 1, 0xd0,
    0xec, 1, 0x04,
    0xed, 1, 0x07,
    0xee, 1, 0x07,
    0xef, 1, 0x09,
    0xf0, 1, 0xd0,
    0xf1, 1, 0x0e,
    0xF9, 1, 0x17,

    0xf2, 4, 0x2c, 0x1b, 0x0b, 0x20,

    0xe9, 1, 0x29,
    0xec, 1, 0x04,
    0x35, 1, 0x00,
    0x44, 2, 0x00, 0x10,
    0x46, 1, 0x10,

    LV_LCD_CMD_DELAY_MS, LV_LCD_CMD_EOF
};

static const uint8_t init_cmd_list_2[] = {
    0x3a, 1, 0x05,
    NV3007_SLPOUT, 0,
    LV_LCD_CMD_DELAY_MS, 22,
    NV3007_DISPON, 0,

    LV_LCD_CMD_DELAY_MS, LV_LCD_CMD_EOF
};

/**********************
 *  STATIC VARIABLES
 **********************/

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

lv_display_t * lv_nv3007_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
                                lv_nv3007_send_cmd_cb_t send_cmd_cb, lv_nv3007_send_color_cb_t send_color_cb)
{
    lv_display_t * disp = lv_lcd_generic_mipi_create(hor_res, ver_res, flags, send_cmd_cb, send_color_cb);

    send_cmd_cb(disp, (const uint8_t[]) {
        0xFF
    }, 1, (const uint8_t[]) {
        0xA5
    }, 1);
    lv_lcd_generic_mipi_send_cmd_list(disp, init_cmd_list);
    send_cmd_cb(disp, (const uint8_t[]) {
        0xFF
    }, 1, (const uint8_t[]) {
        0x00
    }, 1);
    lv_lcd_generic_mipi_send_cmd_list(disp, init_cmd_list_2);
    return disp;
}

void lv_nv3007_set_gap(lv_display_t * disp, uint16_t x, uint16_t y)
{
    lv_lcd_generic_mipi_set_gap(disp, x, y);
}

void lv_nv3007_set_invert(lv_display_t * disp, bool invert)
{
    lv_lcd_generic_mipi_set_invert(disp, invert);
}

void lv_nv3007_set_gamma_curve(lv_display_t * disp, uint8_t gamma)
{
    lv_lcd_generic_mipi_set_gamma_curve(disp, gamma);
}

void lv_nv3007_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list)
{
    lv_lcd_generic_mipi_send_cmd_list(disp, cmd_list);
}

/**********************
 *   STATIC FUNCTIONS
 **********************/

#endif /*LV_USE_NV3007*/
